package core;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import dao.AccountInfo;
import dao.CacheD;
import dao.ProxyConfig;
import dao.Result;
import main.MyStart;
import okhttp3.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import utils.*;

import javax.crypto.Cipher;
import java.io.IOException;
import java.net.*;
import java.security.KeyFactory;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class UpdatePassword {

    private  String xDatadomeClientid;
    private  String cookie;

    // 0-改密 1-检查
    private  int options;

     String key ;
     String account ;
     String password ;
     String ssoKey ;
     String acSession ;
     String cookieDatadome ;
     CacheD cache=new CacheD();

     int loginRetryCount=0;
     int rUpdta=0;
     int rUpdtaMax=2;
     String addr_security;

     String addr_gamecenter;
     String userAgent;
     String language = "en-SG" ;
     ProxyConfig proxyConfig;
     Proxy proxy = null;

    private AccountInfo config;

     LoggerUtile logger = null;
     boolean isSession;
     String publicKey =
                    "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDR7FHnzqB8syM62mAJAG7z6/ie" +
                    "/Vz3eq0hEFHQCAd9xxQocrjDbulx1LNox5wTprvLibVRqDCMaPcXZMFRnerZC1YO" +
                    "Ems2U3VwDMWi5s+B4qD+6jG1PB+NPzrlIt+asZtcDDkdmX1t5WgHMoubvV9tCOpH" +
                    "YUBgF34S9lvbldXW4wIDAQAB";
     int passwordChangeMaxRetryCount = 3;
     int passwordChangeRetryCount = 0;

     int getUGDatadomeRetryCount = 0;

    private  String cookie2;
    private String cookie1;

    public  void initProxxy(){
        if (proxyConfig != null) {
            proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(proxyConfig.getIp(),proxyConfig.getPort()));
            java.net.Authenticator.setDefault(new java.net.Authenticator() {
                private PasswordAuthentication authentication = new PasswordAuthentication("d3428219915", "yb134jr2".toCharArray());
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return authentication;
                }
            });
        }
    }

    public  Result start(AccountInfo accountInfo,ProxyConfig proxyConfig1, int taskType,String addr1, String addr2) {
            userAgent = String.valueOf(UUID.randomUUID());
            config = accountInfo;
            logger=LoggerUtile.getLogger("garenaJava-pwd-update-"+config.getHaoId()+" - "+config.getOrderId());
            proxyConfig = proxyConfig1;
            key = config.getGarenaKey();
            account =   config.getAccount();
            password =  config.getPassword();
            options = taskType;
            addr_security = addr1;
            addr_gamecenter = addr2;
            logger.info("开始改密/检查任务7.1版本" + "account:" + account + " password:" + password);
            initProxxy();
            // 提前检查Key
            if (!checkKey()) { //3.1 检查key
                return new Result(62,"无效的身份验证器",JSON.toJSONString(accountInfo));
            }
            // Replace this with the appropriate code for getSession
            //getSession();
            return getClientID();
    }


     boolean checkKey(){
        try{
            new Totp().generateTOTP(key,180);
            return true;
        }catch (Exception e){
            logger.error("无效的身份验证器" + e);
            Map m = new HashMap();
            m.put("key",key);
            m.put("message",e);
            return false;
        }
    }

     void getSession(){
        try {
            String sData = Tools.getSession(account);
            logger.info("查询redis结果：" +sData );
            if(StringUtils.isBlank(sData)){
                getClientID();
                return;
            }
            JSONObject parse = (JSONObject) JSONObject.parse(sData);
            //当前时间减去5分钟
            long fiveMinutesAgoTimestamp  = System.currentTimeMillis() - (5 * 60 * 1000);
            if(parse!=null && parse.get("cookie")!=null  &&  parse.get("time")!=null &&  (fiveMinutesAgoTimestamp < (parse.getLong("time")+(7L * 24 * 60 * 60 * 1000)))){
                logger.info("session已经存在 尝试复用" + sData);
                cookie = sData;
                isSession = true;
                preverify();
                return;
            }
            logger.info("session不存在 重新登录");
            // prelogin();
            getClientID();
        } catch (Exception e) {
            // Handle exceptions as needed

            logger.info("session不存在 重新登录" +e.getMessage());
            // this.prelogin()
            getClientID();
        }
    }

    Result getClientID() { //3.2datadome
//        logger.info("开始请求获取datadome...");
        try {
            String cid = null;
            String jspl = V8Utils.getJspl(cid == null ? "" : cid);
            String eventCounters = null;
            String jsType = null;
            if (cid == null) {
                eventCounters = "[]";
                jsType = "ch";
            } else {
                eventCounters = "{\"mousemove\":161,\"click\":0,\"scroll\":0,\"touchstart\":0,\"touchend\":0,\"touchmove\":0,\"keydown\":0,\"keyup\":0}";
                jsType = "le";
            }
            String ddk = "AE3F04AD3F0D3A462481A337485081";
            String Referer = "https%3A%2F%2Fsso.garena.com%2Funiversal%2Flogin%3Fapp_id%3D10100%26redirect_uri%3Dhttps%253A%252F%252Faccount.garena.com%252F%26locale%3Den-SG";
            String request = "%2Funiversal%2Flogin%3Fapp_id%3D10100%26redirect_uri%3Dhttps%253A%252F%252Faccount.garena.com%252F%26locale%3Den-SG";
            String responsePage = "origin";
            String ddv = "4.46.0-next";
            String body = String.format("jspl=%s&eventCounters=%s&jsType=%s&cid=%s&ddk=%s&Referer=%s&request=%s&responsePage=%s&ddv=%s", jspl, URLEncoder.encode(eventCounters), jsType, cid, ddk, URLEncoder.encode(Referer), URLEncoder.encode(request), responsePage, ddv);
            if (cid == null) {
                body = String.format("jspl=%s&eventCounters=%s&jsType=%s&ddk=%s&Referer=%s&request=%s&responsePage=%s&ddv=%s", jspl, URLEncoder.encode(eventCounters), jsType, ddk, URLEncoder.encode(Referer), URLEncoder.encode(request), responsePage, ddv);
            }
            logger.info("开始请求获取datadome...");
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("content-type", "application/x-www-form-urlencoded");
            headerMap.put("priority", "u=1, i");
            headerMap.put("sec-ch-ua", "\"Google Chrome\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"");
            headerMap.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36");

            Response response = OkHttpClientUtils.doFormPost("https://dd.garena.com/js/", headerMap, body, proxy);
            String reslut = response.body().string();

            logger.info("获取datadome结果" + reslut);

            cookie1 = JSONObject.parseObject(reslut).getString("cookie");
            if (cookie1 == null) {
                return new Result(-1, "获取datadome异常","返回数据中cookie为空");
            }
            xDatadomeClientid = cookie1.split(";")[0].split("=")[1];

            return prelogin();
        } catch (Exception e){
            logger.error("获取datadome请求异常" + e.getMessage());
            return new Result(-1,"获取datadome请求异常"+e.getMessage(),e.getMessage());
        }

    }


//    Result getClientID(){ //3.2datadome
//        logger.info("开始请求获取datadome,分2步");
//        try {
//            //1cid
////            String jdata1 = "jsData=%7B%22ttst%22%3A7.5%2C%22ifov%22%3Afalse%2C%22hc%22%3A12%2C%22br_oh%22%3A1032%2C%22br_ow%22%3A1920%2C%22ua%22%3A%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F129.0.0.0%20Safari%2F537.36%22%2C%22wbd%22%3Afalse%2C%22tagpu%22%3A9.87811443857472%2C%22wdif%22%3Afalse%2C%22wdifrm%22%3Afalse%2C%22npmtm%22%3Afalse%2C%22br_h%22%3A911%2C%22br_w%22%3A1920%2C%22isf%22%3Afalse%2C%22nddc%22%3A1%2C%22rs_h%22%3A1080%2C%22rs_w%22%3A1920%2C%22rs_cd%22%3A24%2C%22phe%22%3Afalse%2C%22nm%22%3Afalse%2C%22jsf%22%3Afalse%2C%22lg%22%3A%22zh-CN%22%2C%22pr%22%3A1%2C%22ars_h%22%3A1032%2C%22ars_w%22%3A1920%2C%22tz%22%3A-480%2C%22str_ss%22%3Atrue%2C%22str_ls%22%3Atrue%2C%22str_idb%22%3Atrue%2C%22str_odb%22%3Afalse%2C%22plgod%22%3Afalse%2C%22plg%22%3A5%2C%22plgne%22%3Atrue%2C%22plgre%22%3Atrue%2C%22plgof%22%3Afalse%2C%22plggt%22%3Afalse%2C%22pltod%22%3Afalse%2C%22hcovdr%22%3Afalse%2C%22hcovdr2%22%3Afalse%2C%22plovdr%22%3Afalse%2C%22plovdr2%22%3Afalse%2C%22ftsovdr%22%3Afalse%2C%22ftsovdr2%22%3Afalse%2C%22lb%22%3Afalse%2C%22eva%22%3A33%2C%22lo%22%3Afalse%2C%22ts_mtp%22%3A0%2C%22ts_tec%22%3Afalse%2C%22ts_tsa%22%3Afalse%2C%22vnd%22%3A%22Google%20Inc.%22%2C%22bid%22%3A%22NA%22%2C%22mmt%22%3A%22application%2Fpdf%2Ctext%2Fpdf%22%2C%22plu%22%3A%22PDF%20Viewer%2CChrome%20PDF%20Viewer%2CChromium%20PDF%20Viewer%2CMicrosoft%20Edge%20PDF%20Viewer%2CWebKit%20built-in%20PDF%22%2C%22hdn%22%3Afalse%2C%22awe%22%3Afalse%2C%22geb%22%3Afalse%2C%22dat%22%3Afalse%2C%22med%22%3A%22defined%22%2C%22aco%22%3A%22probably%22%2C%22acots%22%3Afalse%2C%22acmp%22%3A%22probably%22%2C%22acmpts%22%3Atrue%2C%22acw%22%3A%22probably%22%2C%22acwts%22%3Afalse%2C%22acma%22%3A%22maybe%22%2C%22acmats%22%3Afalse%2C%22acaa%22%3A%22probably%22%2C%22acaats%22%3Atrue%2C%22ac3%22%3A%22%22%2C%22ac3ts%22%3Afalse%2C%22acf%22%3A%22probably%22%2C%22acfts%22%3Afalse%2C%22acmp4%22%3A%22maybe%22%2C%22acmp4ts%22%3Afalse%2C%22acmp3%22%3A%22probably%22%2C%22acmp3ts%22%3Afalse%2C%22acwm%22%3A%22maybe%22%2C%22acwmts%22%3Afalse%2C%22ocpt%22%3Afalse%2C%22vco%22%3A%22%22%2C%22vcots%22%3Afalse%2C%22vch%22%3A%22probably%22%2C%22vchts%22%3Atrue%2C%22vcw%22%3A%22probably%22%2C%22vcwts%22%3Atrue%2C%22vc3%22%3A%22maybe%22%2C%22vc3ts%22%3Afalse%2C%22vcmp%22%3A%22%22%2C%22vcmpts%22%3Afalse%2C%22vcq%22%3A%22%22%2C%22vcqts%22%3Afalse%2C%22vc1%22%3A%22probably%22%2C%22vc1ts%22%3Atrue%2C%22dvm%22%3A8%2C%22sqt%22%3Afalse%2C%22so%22%3A%22landscape-primary%22%2C%22wdw%22%3Atrue%2C%22cokys%22%3A%22bG9hZFRpbWVzY3NpYXBwL%3D%22%2C%22ecpc%22%3Afalse%2C%22lgs%22%3Atrue%2C%22lgsod%22%3Afalse%2C%22psn%22%3Atrue%2C%22edp%22%3Atrue%2C%22addt%22%3Atrue%2C%22wsdc%22%3Atrue%2C%22ccsr%22%3Atrue%2C%22nuad%22%3Atrue%2C%22bcda%22%3Afalse%2C%22idn%22%3Atrue%2C%22capi%22%3Afalse%2C%22svde%22%3Afalse%2C%22vpbq%22%3Atrue%2C%22ucdv%22%3Afalse%2C%22spwn%22%3Afalse%2C%22emt%22%3Afalse%2C%22bfr%22%3Afalse%2C%22dbov%22%3Afalse%2C%22cfpfe%22%3A%22ZnVuY3Rpb24oKXt2YXIgdD1kb2N1bWVudFsnXHg3MVx4NzVceDY1XHg3Mlx4NzlceDUzXHg2NVx4NmNceDY1XHg2M1x4NzRceDZmXHg3MiddKCdceDYyXHg3Mlx4NmZceDc3XHg3M1x4NjVceDcyXHg2Nlx4NmNceDZmXHg3N1x4MmRceDYzXHg2Zlx4NmVceDc0XHg2%22%2C%22stcfp%22%3A%22ciAoaHR0cHM6Ly9kZC5nYXJlbmEuY29tL3RhZ3MuanM6Mjo4MzYzOCkKICAgIGF0IHQuZXhwb3J0cy5kZF9hYyAoaHR0cHM6Ly9kZC5nYXJlbmEuY29tL3RhZ3MuanM6MjoxMDI2NDMpCiAgICBhdCBodHRwczovL2RkLmdhcmVuYS5jb20vdGFncy5qczoyOjU5MjIz%22%2C%22ckwa%22%3Atrue%2C%22prm%22%3Atrue%2C%22tzp%22%3A%22Asia%2FShanghai%22%2C%22cvs%22%3Atrue%2C%22usb%22%3A%22defined%22%2C%22emd%22%3A%22k%3Aao%22%2C%22glvd%22%3A%22Google%20Inc.%20(Intel)%22%2C%22glrd%22%3A%22ANGLE%20(Intel%2C%20Intel(R)%20UHD%20Graphics%20770%20(0x00004690)%20Direct3D11%20vs_5_0%20ps_5_0%2C%20D3D11)%22%2C%22wwl%22%3Afalse%2C%22jset%22%3A"+System.currentTimeMillis()/1000+"%7D&eventCounters=%5B%5D&jsType=ch&cid=7o_EUe1CziUlmb3IhiIHO~rXE_C1CJGbCMFjz1z~A_sWrBPIwUlhbluR_KhSy42mwZ5VryH4jb43u7t7RNB0dJbqpKAmqStT9b6o3gbjxnJiSAC8eIb79_oPAztP7cdu&ddk=AE3F04AD3F0D3A462481A337485081&Referer=https%253A%252F%252Faccount.garena.com%252F%253Fsession_key%253D47bbe7479ac577c12033b706d3475791aaa8a759b196ca28e04dc11f64e1dc5e&request=%252F%253Fsession_key%253D47bbe7479ac577c12033b706d3475791aaa8a759b196ca28e04dc11f64e1dc5e&responsePage=origin&ddv=4.35.3";
//
//            String jspl = V8Utils.getJspl("");
//            String jdata = "jspl=" +jspl+
//                    "&eventCounters=%5B%5D&jsType=ch&cid=null&ddk=AE3F04AD3F0D3A462481A337485081&Referer=https%253A%252F%252Faccount.garena.com%252F%253Fsession_key%253D47bbe7479ac577c12033b706d3475791aaa8a759b196ca28e04dc11f64e1dc5e&request=%252F%253Fsession_key%253D47bbe7479ac577c12033b706d3475791aaa8a759b196ca28e04dc11f64e1dc5e&responsePage=origin&ddv=4.45.1-next";
//
//            String body1 = HttpRequest.post("https://dd.garena.com/js/")
//                    .header("sec-ch-ua-platform", "\"Windows\"")
//                    .header("User-Agent", userAgent)
//                    .header("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"")
//                    .header("content-type", "application/x-www-form-urlencoded")
//                    .header("sec-ch-ua-mobile", "?0")
//                    .header("accept", "*/*")
//                    .header("origin", "https://account.garena.com")
//                    .header("Sec-Fetch-Site", "same-origin")
//                    .header("Sec-Fetch-Mode", "cors")
//                    .header("Sec-Fetch-Dest", "empty")
//                    .header("Referer", "https://account.garena.com/")
//                    .header("Accept-Language", "zh-CN,zh;q=0.9")
//                    .body(jdata)
//                    .setReadTimeout(40000)
//                    .setConnectionTimeout(40000)
//                    .timeout(40000)
//                    .setProxy(proxy)
//                    .executeAsync()
//                    .body();
//            JSONObject data1 = (JSONObject) JSONObject.parse(body1);
//            String cookie11 = (String) data1.get("cookie");
//            String cid = cookie11.split(";")[0].split("=")[1];
//            logger.info("首次请求datadome接口，获取cid:"+cid);
//            //2
//            jspl= V8Utils.getJspl("");
//            jdata = "jspl=" +jspl+
//                    "&eventCounters=%5B%5D&jsType=ch&cid=" + cid + "&ddk=AE3F04AD3F0D3A462481A337485081&Referer=https%253A%252F%252Faccount.garena.com%252F%253Fsession_key%253D47bbe7479ac577c12033b706d3475791aaa8a759b196ca28e04dc11f64e1dc5e&request=%252F%253Fsession_key%253D47bbe7479ac577c12033b706d3475791aaa8a759b196ca28e04dc11f64e1dc5e&responsePage=origin&ddv=4.45.1-next";
//            String body = HttpRequest.post("https://dd.garena.com/js/")
//                    .header("sec-ch-ua-platform", "\"Windows\"")
//                    .header("User-Agent", userAgent)
//                    .header("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"")
//                    .header("content-type", "application/x-www-form-urlencoded")
//                    .header("sec-ch-ua-mobile", "?0")
//                    .header("accept", "*/*")
//                    .header("origin", "https://account.garena.com")
//                    .header("Sec-Fetch-Site", "same-origin")
//                    .header("Sec-Fetch-Mode", "cors")
//                    .header("Sec-Fetch-Dest", "empty")
//                    .header("Referer", "https://account.garena.com/")
//                    .header("Accept-Language", "zh-CN,zh;q=0.9")
//                    .body(jdata)
//                    .setReadTimeout(40000)
//                    .setConnectionTimeout(40000)
//                    .timeout(40000)
//                    .setProxy(proxy)
//                    .executeAsync()
//                    .body();
//            JSONObject data = (JSONObject) JSONObject.parse(body);
//            logger.info("获取datadome结果" + data);
//            cookie1 = (String) data.get("cookie");
//            if (cookie1 == null) {
//                return new Result(10, "获取datadome异常", data);
//            }
//            xDatadomeClientid = cookie1.split(";")[0].split("=")[1];
//            return prelogin();
//        }catch (Exception e){
//            logger.error("获取datadome请求异常" + e.getMessage());
//            return new Result(-1,"获取datadome请求异常"+e.getMessage(),e.getMessage());
//        }
//    }

    /**
     * 提交验证码(datadome cookie值导致的)
     * @param codeUrl
     * @param flagTag 1：预登录 2 改密
     * @return
     */
    boolean saveDatadomeCodeUrl(String codeUrl, int flagTag){
        String url = "http://"+addr_security+"/api/v1/security/account/saveCodeUrl";
        logger.info("开始提交验证码接口url：" + url+",codeUrl:"+codeUrl+",flagTag:"+flagTag);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("codeUrl",codeUrl);
        jsonObject.put("flagTag", flagTag);
        try {
            Response response = OkHttpClientUtils.doPost(url,jsonObject.toJSONString());
            String resultStr = response.body().string();
            JSONObject parse = JSONObject.parseObject(resultStr);
            if (parse.getIntValue("status") ==1){
                return true;
            } else {
                logger.error("提交验证码接口报错，status值错误,status="+parse.getIntValue("status")+",code:"+response.code());
                return false;
            }

        } catch (IOException e) {
            logger.error("提交验证码接口报错：" + e.getMessage());
            return false;
        }
    }

    /**
     * 轮询获取
     * @param flagTag 1：预登录 2 改密
     * @return
     */
    String loopGetDatadomwCode(int flagTag){
        String tempDatadomeCookie = "";
        while (getUGDatadomeRetryCount<=5){
            tempDatadomeCookie = getDatadomeCode(flagTag);
            if (tempDatadomeCookie != null && !"".equals(tempDatadomeCookie)){
                getUGDatadomeRetryCount =0;
                return tempDatadomeCookie;
            }
        }
        getUGDatadomeRetryCount =0;
        return tempDatadomeCookie;
    }

    /**
     * 获取datadomecode对应cookie值
     * @param flagTag 1：预登录 2 改密
     * @return
     */
    String getDatadomeCode(int flagTag){
        getUGDatadomeRetryCount++;
        String tempDatadomeCookie = "";
        String url = "http://"+addr_security+"/api/v1/security/account/getCookie";
        logger.info("开始请求获取验证码接口url：" + url+",flagTag:"+flagTag);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("flagTag", flagTag);
        try {
            Thread.sleep(5000);
            Response response = OkHttpClientUtils.doPost(url,jsonObject.toJSONString());
            String resultStr = response.body().string();
            JSONObject parse = JSONObject.parseObject(resultStr);
            if (parse.getIntValue("status") ==1){
                if (parse.get("data") == null){
                    logger.error("获取datadomecode对应cookie接口data为空：");
                    return tempDatadomeCookie;
                }
                JSONObject cookieJson = JSONObject.parseObject(parse.getString("data"));
                if (null == cookieJson.get("cookieValue")){
                    logger.error("获取datadomecode对应cookie接口，cookieValue值不存在");
                    return tempDatadomeCookie;
                }
                String encodedString = cookieJson.getString("cookieValue");
                String decodedString = URLDecoder.decode(encodedString, "UTF-8");

                JSONObject cookieResultObject = JSONObject.parseObject(decodedString);
                return cookieResultObject.getString("cookie");
            } else {
                logger.error("获取datadomecode对应cookie接口报错，status="+parse.getIntValue("status")+",code:"+response.code());
                return tempDatadomeCookie;
            }

        } catch (Exception e) {
            logger.error("获取datadomecode对应cookie接口错误：" + e.getMessage());
            return tempDatadomeCookie;
        }
    }


    Result prelogin(){ //3.2预登录
        try {
            Map<String, String> headers = new HashMap<>();
            headers.put("Host", "sso.garena.com");
            headers.put("Connection", "keep-alive");
            headers.put("sec-ch-ua-platform", "\"Windows\"");
            headers.put("User-Agent", userAgent);
            headers.put("Accept", "application/json, text/plain, */*");
            headers.put("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"");
            headers.put("sec-ch-ua-mobile", "?0");
            headers.put("Sec-Fetch-Site", "same-origin");
            headers.put("Sec-Fetch-Mode", "cors");
            headers.put("Sec-Fetch-Dest", "empty");
            headers.put("Referer", "https://sso.garena.com/universal/login?app_id=10100&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&locale=en-SG");
            headers.put("Accept-Language", "zh-CN,zh;q=0.9");
            headers.put("Cookie", cookie1);
            Response response = OkHttpClientUtils.doGetByProxy("https://sso.garena.com/api/prelogin?app_id=10100&account=" + account + "&format=json&id=" + System.currentTimeMillis(), headers, proxy);
            JSONObject parse = (JSONObject) JSONObject.parse(response.body().string());
            //logger.info("预登录param cookie1:" + cookie1);
            logger.info("预登录结果" + parse);
            if (parse.get("error") != null && parse.get("error").equals("error_require_datadome_cookie")) {
                logger.info("error_require_datadome_cookie");
                return new Result(24, "equire_datadome_cookie", parse.get("error"));
            }

            if (parse.get("url") != null) {
                String captcha = parse.getString("url");
                if(captcha.startsWith("https://geo.captcha-delivery.com/captcha")){ //已经被锁定了，不用再重复请求cookie
                    return new Result(-1, "预登录出现验证码，已经被锁定了！", parse);
                }
                //处理验证码
                boolean isSave = saveDatadomeCodeUrl(captcha, 1);
                if (!isSave){
                    return new Result(-23, "需要验证码！保存验证码到服务器接口时候出错！", parse);
                }
                //Thread.sleep(5000);
                String tempCookie = loopGetDatadomwCode(1);
                logger.info("预登录验证码处理cookie1:" + tempCookie);
                if (tempCookie == null || "".equals(tempCookie)){
                    return new Result(-1, "预登录出现验证码，获取最新cookie出错！", parse);
                }
                if (tempCookie.equals(cookie1)){
                    return new Result(23, "预登录出现验证码，获取最新cookie有误，新cookie和原始cookie一致！", parse);
                }
                cookie1 = tempCookie;
                xDatadomeClientid = cookie1.split(";")[0].split("=")[1];
                return prelogin();
            }

            if (parse != null && parse.get("error") != null && parse.get("error").equals("error_no_account")) {
                return new Result(20, "账号不存在", parse);
            }
            if (parse.get("v1") == null) {
                // 处理另外一种形式的谷歌验证码
                if (parse.get("error").equals("error_require_recaptcha_token") || parse.get("error").equals("error_recaptcha_token")) {
                    return getReCaptchaSiteKeyFromCurrentSite();
                }
                logger.info("预登录异常" + parse);
                return new Result(21, "预登录异常", parse);
            }
            String hs = response.header("X-Datadome");
            if (hs != null) {
                cookieDatadome = response.header("Set-Cookie").split(";")[0].split("=")[1];

            }

            return login(parse);
        } catch (Exception e) {
            logger.error("预登录处理异常" + e.getMessage());
            return new Result(-1, "预登录处理异常" + e.getMessage(), e.getMessage());
        }
    }

    public  Result getReCaptchaSiteKeyFromCurrentSite(){
        try {
//            String body = HttpRequest.get("https://sso.garena.com/ui/login?app_id=10100&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&locale=id-ID")
//                    .header("User-Agent", userAgent)
//                    .header("Referrer-Policy", "strict-origin-when-cross-origin")
//                    .header("Accept-Encoding", "gzip, deflate, br")
//                    .header("Accept-language", "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7,en-US;q=0.6")
//                    .header("Cache-Control","no-cache")
//                    .header("Connection","keep-alive")
//                    .header("Pragma", "no-cache")
//                    .header("Referer", "https://sso.garena.com/")
//                    .header("Upgrade-Insecure-Requests", "1")
//                    .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
//                    .setProxy(proxy)
//                    .execute().body();
            Map<String, String> headers = new HashMap<>();
            headers.put("User-Agent", userAgent);
            headers.put("Referrer-Policy", "strict-origin-when-cross-origin");
            headers.put("Accept-Encoding", "gzip, deflate, br");
            headers.put("Accept-language", "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7,en-US;q=0.6");
            headers.put("Cache-Control","no-cache");
            headers.put("Connection","keep-alive");
            headers.put("Pragma", "no-cache");
            headers.put("Referer", "https://sso.garena.com/");
            headers.put("Upgrade-Insecure-Requests", "1");
            headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
            Response response =  OkHttpClientUtils.doGetByProxy("https://sso.garena.com/ui/login?app_id=10100&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&locale=id-ID",
                    headers ,proxy);
            JSONObject Odata = (JSONObject) JSONObject.parse(response.body().string());
            JSONObject datas = (JSONObject) Odata.get("data");
            logger.info("siteKey查询完成" + datas);
            if (datas.get("recaptcha_site_key")!=null) {
                String regex = "['\"]recaptcha_site_key['\"]\\s*:\\s*['\"](.*?)['\"]";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher((CharSequence) datas);
               return createReCaptchaTaskByYesCaptcha(matcher.group(1), "https://sso.garena.com/ui/login?app_id=10100&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&locale=id-ID");
            }
        }catch (Exception e){
            logger.error("siteKey查询异常" +  e.getMessage());
            return new Result(-1,"请求siteKey异常",e.getMessage());
        }
        return null;
    }

    public  Result createReCaptchaTaskByYesCaptcha(String websiteKey,String url){
        try {
            Map md=new HashMap();
            Map mt=new HashMap();
            mt.put("websiteURL",url);
            mt.put("websiteKey",websiteKey);
            mt.put("type","NoCaptchaTaskProxyless");
            md.put("clientKey","11ad877f9a5f2002bfc6220e83ff9bd7e458ce8d26149");
            md.put("task",mt);
            String s = JSON.toJSONString(md);
            /*String body = HttpRequest.post(url)
                    .body(s)
                    .setProxy(proxy)
                    .execute().body();*/


            Response response = OkHttpClientUtils.doPost(url, null, s, proxy);

            JSONObject data = (JSONObject) JSONObject.parse(response.body().string());
            logger.info("人机验证任务创建结果" + data);
            JSONObject taskId = (JSONObject) JSONObject.parse(JSON.toJSONString(data.get("taskId")));
            if (taskId.size()>0) {
                return getReCaptchaResultByYesCaptcha(JSON.toJSONString(data.get("taskId")));
            }
            return new Result(100,"人机验证任务创建异常",data);
        }catch (Exception e){
            logger.error("人机验证任务创建异常" + e.getMessage());
           return new Result(-1,"人机验证任务创建请求异常",e.getMessage());
        }
    }
    // 查询任务处理进度 yescaptcha.com
    public  Result getReCaptchaResultByYesCaptcha(String id){
        JSONObject data=null;
        try {
            Map md= new HashMap();
            md.put("clientKey","11ad877f9a5f2002bfc6220e83ff9bd7e458ce8d26149");
            md.put("taskId",id);
            String s = JSON.toJSONString(md);
            /*String body = HttpRequest.post("https://api.yescaptcha.com/getTaskResult")
                    .body(s)
                    .setProxy(proxy)
                    .execute().body();*/
            Response response = OkHttpClientUtils.doPost("https://api.yescaptcha.com/getTaskResult", null, s, proxy);

            data = (JSONObject) JSONObject.parse(response.body().string());
            logger.info("人机验证任务轮询结果" + data);
            if (data.get("status").equals("processing")) {
                Timer timer = new Timer();
                // 每隔60秒执行一次updateZingspeedPasswordTask
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        getReCaptchaResultByYesCaptcha(id);
                    }
                }, 0, 5000);
                return null;
            }

            if (data.get("status").equals("ready")) {
                logger.info("人机验证任务完成");
                JSONObject solution = (JSONObject) data.get("solution");
                prelogin();
            //    solveReCaptcha((String) solution.get("gRecaptchaResponse" ));
                // this.prelogin(data.solution.gRecaptchaResponse)
                return null;
            }
            return new Result(90,"人机验证任务异常",data);
        }catch (Exception e){
            logger.error("人机验证任务失败"  + e.getMessage());
            return new Result(-1,"人机验证任务请求异常",e.getMessage());
        }
    }
    // 验证人机验证结果
     void solveReCaptcha(String s){
        try {

        }catch (Exception e){

        }
    }

    public  Result login(Object data){//3.3登录
        try {

            JSONObject Jdata = (JSONObject) JSONObject.parse(JSON.toJSONString(data));
            String passwordMD5 = MyMD5Util.md5(password);
            String passwordKey = MyMD5Util.getSHA256StrJava(MyMD5Util.getSHA256StrJava(passwordMD5 + Jdata.get("v1")) + Jdata.get("v2"));
            String encryptedPasswordNew = MyMD5Util.AES(passwordMD5, passwordKey);
//            HttpResponse execute = HttpRequest.get("https://sso.garena.com/api/login?account=" + account + "&password=" + encryptedPasswordNew + "&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&format=json&id=" + System.currentTimeMillis() + "&app_id=10100")
//                    .header("Host", "sso.garena.com")
//                    .header("Connection", "keep-alive")
//                    .header("sec-ch-ua-platform", "\"Windows\"")
//                    .header("User-Agent", userAgent)
//                    .header("Accept", "application/json, text/plain, */*")
//                    .header("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"")
//                    .header("sec-ch-ua-mobile", "?0")
//                    .header("Sec-Fetch-Site", "same-origin")
//                    .header("Sec-Fetch-Mode", "cors")
//                    .header("Sec-Fetch-Dest", "empty")
//                    .header("Referer", "https://sso.garena.com/universal/login?app_id=10100&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&locale=en-SG")
//                    .header("Accept-Language", "zh-CN,zh;q=0.9")
//                    .header("Cookie", "datadome=" + cookieDatadome)
//                    .setProxy(proxy)
//                    .setReadTimeout(40000)
//                    .setConnectionTimeout(40000)
//                    .timeout(40000)
//                    .executeAsync();


            Map<String, String> headers = new HashMap<>();
            headers.put("Host", "sso.garena.com");
            headers.put("Connection", "keep-alive");
            headers.put("sec-ch-ua-platform", "\"Windows\"");
            headers.put("User-Agent", userAgent);
            headers.put("Accept", "application/json, text/plain, */*");
            headers.put("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"");
            headers.put("sec-ch-ua-mobile", "?0");
            headers.put("Sec-Fetch-Site", "same-origin");
            headers.put("Sec-Fetch-Mode", "cors");
            headers.put("Sec-Fetch-Dest", "empty");
            headers.put("Referer", "https://sso.garena.com/universal/login?app_id=10100&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&locale=en-SG");
            headers.put("Accept-Language", "zh-CN,zh;q=0.9");
            headers.put("Cookie", "datadome=" + cookieDatadome);

            Response response = OkHttpClientUtils.doGetByProxy("https://sso.garena.com/api/login?account=" + account + "&password=" + encryptedPasswordNew + "&redirect_uri=https%3A%2F%2Faccount.garena.com%2F&format=json&id=" + System.currentTimeMillis() + "&app_id=10100",
                    headers, proxy);

            JSONObject datas = (JSONObject) JSONObject.parse(response.body().string());
            Map<String, List<String>> headers1 = response.headers().toMultimap();

            logger.info("登录结果："+ datas );

                if(datas.get("error")!=null){
                    //账号被封
                    if (datas.get("error").equals("error_user_ban")) {
                        return new Result(32,"账号已被封禁",datas);
                    }
                    // 提示参数错误 或密码错误 有一定概率误报 重试
                    if (datas.get("error").equals("error_params") || datas.get("error").equals("error_auth")) {
                        loginRetryCount = (loginRetryCount != 0) ? loginRetryCount + 1 : 1;
                        logger.info("登录异常重试"  + loginRetryCount );
                        if (loginRetryCount >= 3) {
                            return new Result(33,"登录异常,参数或密码错误",datas);
                        } else {
                            //重新获取cookiedemo
                            return getClientID();
                        }
                    }
                }


            String setcookie= headers1.get("Set-Cookie").get(0);
            if(setcookie==null){
                logger.info("登录异常未找到登录Cookie");
                return new Result(31,"登录异常未找到登录Cookie",datas);
            }
            ssoKey = JSON.toJSONString(setcookie).split(";")[0].split("=")[1];
            return getAcSession(datas.get("redirect_uri"));
        }catch (Exception e){

            logger.error("登录异常" +e.getMessage());
            return new Result(-1,"登录异常" +e.getMessage(),e.getMessage());
        }
    }

    public  Result getAcSession(Object referer){ //3.4获取acsession
        try {
            cookie2 = "datadome="+cookieDatadome+"; sso_key="+ssoKey;
//            HttpRequest.get(referer.toString())
//                    .header("accept-language", "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7,en-US;q=0.6")
//                    .header("pragma", "no-cache")
//                    .header("cache-control", "no-cache")
//                    .header("Referrer-Policy", "strict-origin-when-cross-origin")
//                    .header("accept", "application/json, text/javascript, */*; q=0.01")
//                    .header("User-Agent", userAgent)
//                    .cookie(cookie2)
//                    .setProxy(proxy)
//                    .setReadTimeout(40000)
//                    .setConnectionTimeout(40000)
//                    .timeout(40000)
//                    .executeAsync();
            Map<String, String> headers = new HashMap<>();
            headers.put("accept-language", "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7,en-US;q=0.6");
            headers.put("pragma", "no-cache");
            headers.put("cache-control", "no-cache");
            headers.put("Referrer-Policy", "strict-origin-when-cross-origin");
            headers.put("accept", "application/json, text/javascript, */*; q=0.01");
            headers.put("User-Agent", userAgent);
            headers.put("Cookie",cookie2);

            OkHttpClientUtils.doGetByProxy(referer.toString(),
                    headers, proxy);


            logger.info("ac_session:登录后再次重新获取js cookie");
            String cid = null;
            String jspl = V8Utils.getJspl(cid == null ? "" : cid);
            String eventCounters = null;
            String jsType = null;
            if (cid == null) {
                eventCounters = "[]";
                jsType = "ch";
            } else {
                eventCounters = "{\"mousemove\":161,\"click\":0,\"scroll\":0,\"touchstart\":0,\"touchend\":0,\"touchmove\":0,\"keydown\":0,\"keyup\":0}";
                jsType = "le";
            }
            String ddk = "AE3F04AD3F0D3A462481A337485081";
            String Referer = "https%3A%2F%2Fsso.garena.com%2Funiversal%2Flogin%3Fapp_id%3D10100%26redirect_uri%3Dhttps%253A%252F%252Faccount.garena.com%252F%26locale%3Den-SG";
            String request = "%2Funiversal%2Flogin%3Fapp_id%3D10100%26redirect_uri%3Dhttps%253A%252F%252Faccount.garena.com%252F%26locale%3Den-SG";
            String responsePage = "origin";
            String ddv = "4.46.0-next";
            String body = String.format("jspl=%s&eventCounters=%s&jsType=%s&cid=%s&ddk=%s&Referer=%s&request=%s&responsePage=%s&ddv=%s", jspl, URLEncoder.encode(eventCounters), jsType, cid, ddk, URLEncoder.encode(Referer), URLEncoder.encode(request), responsePage, ddv);
            if (cid == null) {
                body = String.format("jspl=%s&eventCounters=%s&jsType=%s&ddk=%s&Referer=%s&request=%s&responsePage=%s&ddv=%s", jspl, URLEncoder.encode(eventCounters), jsType, ddk, URLEncoder.encode(Referer), URLEncoder.encode(request), responsePage, ddv);
            }
            logger.info("开始请求获取datadome...");
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("content-type", "application/x-www-form-urlencoded");
            headerMap.put("priority", "u=1, i");
            headerMap.put("sec-ch-ua", "\"Google Chrome\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"");
            headerMap.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36");

            Response response1 = OkHttpClientUtils.doFormPost("https://dd.garena.com/js/", headerMap, body, proxy);
            String reslut = response1.body().string();

            logger.info("获取datadome结果" + reslut);

            String tempCookie = reslut.split(";")[0].split("=")[1];
            logger.info("ac_session:获取到的js cookie:"+tempCookie);
            cookieDatadome=tempCookie;
            cookie2 = "datadome=" + cookieDatadome + "; sso_key=" + ssoKey;

//            HttpResponse execute = HttpRequest.get("https://account.garena.com/api/account/init")
//                    .header("Host", "account.garena.com")
//                    .header("Connection", "keep-alive")
//                    .header("sec-ch-ua-platform", "\"Windows\"")
//                    .header("User-Agent", userAgent)
//                    .header("Accept", "application/json, text/plain, */*")
//                    .header("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"")
//                    .header("sec-ch-ua-mobile", "?0")
//                    .header("Sec-Fetch-Site", "same-origin")
//                    .header("Sec-Fetch-Mode", "cors")
//                    .header("Sec-Fetch-Dest", "empty")
//                    .header("Referer", "https://account.garena.com/")
//                    .header("Accept-Language", "zh-CN,zh;q=0.9")
//                    .header("Cookie", cookie2)
//
//                    .setProxy(proxy)
//                    .setReadTimeout(40000)
//                    .setConnectionTimeout(40000)
//                    .timeout(40000)
//                    .executeAsync();

            Map<String, String> newHeader = new HashMap<>();
            newHeader.put("Host", "account.garena.com");
            newHeader.put("Connection", "keep-alive");
            newHeader.put("sec-ch-ua-platform", "\"Windows\"");
            newHeader.put("User-Agent", userAgent);
            newHeader.put("Accept", "application/json, text/plain, */*");
            newHeader.put("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"");
            newHeader.put("sec-ch-ua-mobile", "?0");
            newHeader.put("Sec-Fetch-Site", "same-origin");
            newHeader.put("Sec-Fetch-Mode", "cors");
            newHeader.put("Sec-Fetch-Dest", "empty");
            newHeader.put("Referer", "https://account.garena.com/");
            newHeader.put("Accept-Language", "zh-CN,zh;q=0.9");
            newHeader.put("Cookie",cookie2);

            Response response = OkHttpClientUtils.doGetByProxy("https://account.garena.com/api/account/init",
                    newHeader, proxy);

            JSONObject datas = (JSONObject) JSONObject.parse(response.body().string());
            Map<String, List<String>> headers1 = response.headers().toMultimap();


            logger.info("ac_session结果" +datas);
            String setcookie= headers1.get("Set-Cookie").get(0);

            if(setcookie == null){
                logger.info("登录异常未找到acSession");
                return new Result(40,"登录异常未找到登录Cookie",datas);
            }
            acSession =  setcookie.split(";")[0].split("=")[1];
            cookie = cookie2 + "; ac_session="+acSession;

           return preverify();
        }catch (Exception e){

            logger.error("登录Session获取异常" +e.getMessage());
            return new Result(-1,"登录Session获取异常",e.getMessage());
        }
    }

    public  Result preverify(){ //3.5身份预验证
        try {
//            String body = HttpRequest.post("https://account.garena.com/api/account/preflight")
//                    .header("Host", "account.garena.com")
//                    .header("Connection", "keep-alive")
//                    .header("sec-ch-ua-platform", "\"Windows\"")
//                    .header("User-Agent", userAgent)
//                    .header("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"")
//                    .header("sec-ch-ua-mobile", "?0")
//                    .header("Accept", "*/*")
//                    .header("Sec-Fetch-Site", "same-origin")
//                    .header("Sec-Fetch-Mode", "cors")
//                    .header("Sec-Fetch-Dest", "empty")
//                    .header("Referer", "https://account.garena.com/security/password/2-step-verification")
//                    .header("Accept-Language", "zh-CN,zh;q=0.9")
//                    .header("Cookie", cookie)
//                    .setProxy(proxy)
//                    .setReadTimeout(40000)
//                    .setConnectionTimeout(40000)
//                    .timeout(40000)
//                    .executeAsync().body();

            Map<String, String> newHeader = new HashMap<>();
            newHeader.put("Host", "account.garena.com");
            newHeader.put("Connection", "keep-alive");
            newHeader.put("sec-ch-ua-platform", "\"Windows\"");
            newHeader.put("User-Agent", userAgent);
            newHeader.put("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"");
            newHeader.put("sec-ch-ua-mobile", "?0");
            newHeader.put("Accept", "*/*");
            newHeader.put("Sec-Fetch-Site", "same-origin");
            newHeader.put("Sec-Fetch-Mode", "cors");
            newHeader.put("Sec-Fetch-Dest", "empty");
            newHeader.put("Referer", "https://account.garena.com/security/password/2-step-verification");
            newHeader.put("Accept-Language", "zh-CN,zh;q=0.9");
            newHeader.put("Cookie", cookie);

            Response response = OkHttpClientUtils.doBaseFormPost("https://account.garena.com/api/account/preflight", newHeader, null, proxy);

            JSONObject datas = (JSONObject) JSONObject.parse(response.body().string());
            if(datas.get("error")!=null && datas.get("error").equals("error_suspicious_ip")){
                return new Result(-1,"IP已被封禁",datas);
            }
           return verify(false);
        }catch (Exception e){

            logger.error("身份验证器验证预检异常" + e.getMessage());
            return new Result(-1,"身份验证器验证预检异常",e.getMessage());
        }
    }
    public  Result verify(boolean isRetry){ //3.6 身份验证器(根据isRetry值 判断是否重新获取key 验证)
        Map<String, Object> formData = new HashMap<>();
        formData.put("ac_type", 1);
//        formData.put("by_email", false);

        try {
            // 生成TOTP验证码
            String totpCode = Totp.generateTOTP(key, 180);
            formData.put("code", totpCode);
            formData.put("tool", 1);
        } catch (Exception error) {
            // 处理无效的身份验证器
            logger.info("无效的身份验证器" +key + error.getMessage());
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("key", key);
            errorData.put("message", error != null ? error.getMessage() : null);
            return new Result(62, "无效的身份验证器", JSON.toJSONString(errorData));
        }

        try {
//            HttpResponse sync = HttpRequest.post("https://account.garena.com/api/account/code/verify")
//                    .header("Host", "account.garena.com")
//                    .header("Connection", "keep-alive")
//                    .header("sec-ch-ua-platform", "\"Windows\"")
//                    .header("User-Agent", userAgent)
//                    .header("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"")
//                    .header("Content-Type", "application/json")
//                    .header("sec-ch-ua-mobile", "?0")
//                    .header("Accept", "*/*")
//                    .header("Origin", "https://account.garena.com")
//                    .header("Sec-Fetch-Site", "same-origin")
//                    .header("Sec-Fetch-Mode", "cors")
//                    .header("Sec-Fetch-Dest", "empty")
//                    .header("Referer", "https://account.garena.com/security/password/2-step-verification")
//                    .header("Accept-Language", "zh-CN,zh;q=0.9")
//                    .header("Cookie", cookie)
//                    .body(JSON.toJSONString(formData))
//                    .setProxy(proxy)
//                    .setReadTimeout(40000)
//                    .setConnectionTimeout(40000)
//                    .timeout(40000)
//                    .executeAsync();

            Map<String, String> newHeader = new HashMap<>();
            newHeader.put("Host", "account.garena.com");
            newHeader.put("Connection", "keep-alive");
            newHeader.put("sec-ch-ua-platform", "\"Windows\"");
            newHeader.put("User-Agent", userAgent);
            newHeader.put("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"");
            newHeader.put("Content-Type", "application/json");
            newHeader.put("sec-ch-ua-mobile", "?0");
            newHeader.put("Accept", "*/*");
            newHeader.put("Origin", "https://account.garena.com");
            newHeader.put("Sec-Fetch-Site", "same-origin");
            newHeader.put("Sec-Fetch-Mode", "cors");
            newHeader.put("Sec-Fetch-Dest", "empty");
            newHeader.put("Referer", "https://account.garena.com/security/password/2-step-verification");
            newHeader.put("Accept-Language", "zh-CN,zh;q=0.9");
            newHeader.put("Cookie", cookie);

            Response response = OkHttpClientUtils.doPost("https://account.garena.com/api/account/code/verify",
                    newHeader, JSON.toJSONString(formData), proxy);

            JSONObject datas = (JSONObject) JSONObject.parse(response.body().string());

            logger.info("身份验证器验证预检完成:" +datas);
            if(datas.get("error")!=null && datas.get("error").equals("error_suspicious_ip")){
                return new Result(-1,"'IP已被封禁'",datas);
            }
            if (datas!=null && datas.get("status")!=null){
                if ((int)datas.get("status") == 0) {
                    int taskType  = options;
                    if (taskType == 1) {
                        return new Result(0,"账号/密码/key验证通过",null);
                    }
                    Map<String, List<String>> headers1 = response.headers().toMultimap();
                    String setcookie= headers1.get("Set-Cookie").get(0);
                    acSession =  setcookie.split(";")[0].split("=")[1];
//                    if(!isSession){
//                        //存入redis
//                        cookie = cookie2 + "; ac_session="+acSession;
//                        Map cMap = new HashMap();
//                        cMap.put("cookie",cookie);
//                        cMap.put("time",System.currentTimeMillis());
//                        String s = JSON.toJSONString(cMap);
//                        Tools.setSession(account,s,System.currentTimeMillis());
//                    }
//                    String cookie3 = cookie2 + "; ac_session=" + acSession;
                   return updatePassword(cookie);
                }

                // 未知异常 重试一次
                if ((int)datas.get("status") == 2) {
                    logger.info("身份验证器与账号不匹配");
                    if (!isRetry) {
                      return  verify(true);
                    }
                }

                if ((int)datas.get("status") == 3) {
                    logger.info("未关联身份验证器或验证错误次数过多" + datas);
                    return new Result(63,"'未关联身份验证器或验证错误次数过多'",datas);
                }
            }

            if (datas.get("error")!=null && datas.get("error").equals("error_session")) {
                logger.info("缓存session无效" +  cookie);
             //   Tools.deleteSession(account);
                // this.getAcSessionFromEmulator()
          //      if(isSession){
                   return getClientID();
//                }else {
//                    prelogin();
//                }
            }

            if (datas.get("error")!=null && datas.get("error").equals("'error_server'")) {
                logger.info("未关联身份验证器或未绑定手机号" + datas);
                return new Result(64,"未关联身份验证器或未绑定手机号",datas);
            }
            return new Result(60,"'身份验证器验证异常'",datas);
        }catch (Exception e){

            logger.error("身份验证器验证请求异常" + e.getMessage());
            return new Result(-1,"身份验证器验证请求异常",e.getMessage());
        }

    }
    public  Result updatePassword(String cookie3){ //3.7改密

       // 创建密码生成器
        Random random = new SecureRandom();
        // 定义密码字符集
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        // 定义密码长度
        int length = 10;
        // 生成密码
        StringBuilder password1 = new StringBuilder("@U");
        for (int i = 0; i < length - 2; i++) {
            char randomChar = characters.charAt(random.nextInt(characters.length()));
            password1.append(randomChar);
        }
        String nextPassword = password1.toString();
        // {"password":"@Uslyn7Hdy","nextPassword":"@U2AHW9fvj"}
        logger.info("开始修改密码:原始密码：" + password +" ,nextPassword:" + nextPassword);
        try {

            String encryptedPassword = encrypt(password, publicKey);
            String encryptedNextPassword = encrypt(nextPassword, publicKey);
            Map mdata = new HashMap<>();
            mdata.put("password",encryptedPassword);
            mdata.put("new_password",encryptedNextPassword);
            mdata.put("captcha_key","");
            mdata.put("captcha","");
            String s = JSON.toJSONString(mdata);
            Map<String, String> headers = new HashMap<>();
            headers.put("Host", "account.garena.com");
            headers.put("Connection", "keep-alive");
            headers.put("sec-ch-ua-platform", "\"Windows\"");
            headers.put("User-Agent", userAgent);
            headers.put("Accept", "application/json");
            headers.put("sec-ch-ua", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"");
            headers.put("Content-Type", "application/json");
            headers.put("sec-ch-ua-mobile", "?0");
            headers.put("Origin", "https://account.garena.com");
            headers.put("Sec-Fetch-Site", "same-origin");
            headers.put("Sec-Fetch-Mode", "cors");
            headers.put("Sec-Fetch-Dest", "empty");
            headers.put("Referer", "https://account.garena.com/security/password/change");
            headers.put("Accept-Language", "zh-CN,zh;q=0.9");
            headers.put("Cookie", cookie3);
            logger.info("修改密码：cookie：" + cookie3);

            Response response = OkHttpClientUtils.doPost("https://account.garena.com/api/account/password/change", headers, s, proxy);

            JSONObject datas =  (JSONObject) JSONObject.parse(response.body().string());
            logger.info("修改密码完成" + datas );
            //{"error":"error_action"}
            if(datas.get("error")!=null && "error_action".equals(datas.get("error")) && rUpdta < rUpdtaMax){
                rUpdta++;
                return getClientID();
            }

            if (datas.get("url") != null) {
                String captcha = datas.getString("url");
                if(captcha.startsWith("https://geo.captcha-delivery.com/captcha")){ //已经被锁定了，不用再重复请求cookie
                    return new Result(-1, "修改密码出现验证码，已经被锁定了！", datas);
                }
                //处理验证码
                boolean isSave = saveDatadomeCodeUrl(captcha, 2);
                if (!isSave){
                    return new Result(-73, "需要验证码！保存验证码到服务器接口时候出错！", datas);
                }
                //Thread.sleep(5000);

                String tempCookie = loopGetDatadomwCode(2);
                logger.info("修改密码验证码处理cookie:" + tempCookie);
                if (tempCookie == null || "".equals(tempCookie)){
                    return new Result(-1, "修改密码出现验证码，获取最新cookie出错！", datas);
                }
                if (cookieDatadome.equals(tempCookie.split(";")[0].split("=")[1])){
                    return new Result(-73, "修改密码出现验证码，获取最新cookie有误，新cookie和原始cookie一致！", datas);
                }

                cookieDatadome = tempCookie.split(";")[0].split("=")[1];

                cookie = "datadome=" + cookieDatadome + "; sso_key=" + ssoKey+ "; ac_session=" + acSession;
                return updatePassword(cookie);
            }

            if(datas!=null){
                if ((int)datas.get("status") == 0) {
                    Map m = new HashMap();
                    m.put("data",datas);
                    m.put("nowPassword",nextPassword);
                    m.put("prevPassword",password);
                    String s1 = JSON.toJSONString(m);
                    return new Result(0,"修改密码成功",s1);
                }
                // 当前密码不正确
                if ((int)datas.get("status") == 5) {
                    logger.info("当前密码错误" + password);
                    String maybePassword = (String) cache.getMaybePassword().get(account);
                    if (maybePassword!=null){
                        cache.getMaybePassword().remove(account);
                        password = maybePassword;
                        return updatePassword(cookie);
                    }
                    Map m = new HashMap();
                    m.put("data",datas);
                    m.put("nowPassword",nextPassword);
                    m.put("prevPassword",password);
                    String s1 = JSON.toJSONString(m);
                    return new Result(-3,"当前密码错误",s1);
                }

                if ((int)datas.get("status") == 1 && (passwordChangeRetryCount < passwordChangeMaxRetryCount)) {
                    passwordChangeRetryCount++;
                    logger.info("生成的密码可能不符合规则进行重试");
                    return updatePassword(cookie);
                }
            }
            Map m = new HashMap();
            m.put("data",datas);
            m.put("nowPassword",password);
            m.put("prevPassword",nextPassword);
            String s1 = JSON.toJSONString(m);
            return new Result(-2,"修改密码异常",s1);
        }catch (Exception e){

            Map m = new HashMap();
            m.put("data",e.getMessage());
            m.put("nowPassword",nextPassword);
            m.put("prevPassword",password);
            String s1 = JSON.toJSONString(m);
            cache.getMaybePassword().put("account",nextPassword);

            logger.error("修改密码请求异常" + nextPassword + password  + e.getMessage());
            return new Result(-1,"修改密码请求异常",e.getMessage());
        }
    }
    public  String encrypt( String str, String publicKey ) throws Exception{
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
        return outStr;
    }
}
